package com.outsourcing.bottle.ui;

import it.sephiroth.android.library.imagezoom.ImageViewTouch;
import it.sephiroth.android.library.imagezoom.ImageViewTouchBase;

import java.io.File;
import java.io.FileOutputStream;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.concurrent.Future;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Animation.AnimationListener;

import com.aviary.android.feather.Constants;
import com.aviary.android.feather.FeatherActivity;
import com.aviary.android.feather.FilterManager;
import com.aviary.android.feather.FilterManager.FeatherContext;
import com.aviary.android.feather.async_tasks.DownloadImageAsyncTask;
import com.aviary.android.feather.async_tasks.ExifTask;
import com.aviary.android.feather.async_tasks.DownloadImageAsyncTask.OnImageDownloadListener;
import com.aviary.android.feather.effects.AbstractEffectPanel.ContentPanel;
import com.aviary.android.feather.graphics.ToolIconsDrawable;
import com.aviary.android.feather.library.content.EffectEntry;
import com.aviary.android.feather.library.filters.FilterLoaderFactory;
import com.aviary.android.feather.library.filters.NativeFilterProxy;
import com.aviary.android.feather.library.services.FutureListener;
import com.aviary.android.feather.library.services.LocalDataService;
import com.aviary.android.feather.library.services.ThreadPoolService;
import com.aviary.android.feather.library.utils.IOUtils;
import com.aviary.android.feather.library.utils.StringUtils;
import com.aviary.android.feather.library.utils.SystemUtils;
import com.aviary.android.feather.library.utils.UIConfiguration;
import com.aviary.android.feather.library.utils.ImageLoader.ImageSizes;
import com.aviary.android.feather.utils.UIUtils;
import com.aviary.android.feather.widget.BottombarViewFlipper;
import com.aviary.android.feather.widget.IToast;
import com.aviary.android.feather.widget.ToolbarView;
import com.outsourcing.bottle.BasicActivity;
import com.outsourcing.bottle.R;
import com.outsourcing.bottle.util.Utility;
/**
 * 
 * @author 06peng
 *
 */
public class CropImage2Activity extends BasicActivity implements OnImageDownloadListener,FeatherContext{

	private static final String TAG = CropImage2Activity.class.getSimpleName();
	private Bitmap mBitmap;
	
	/** session id for the hi-res post processing */
	private String mSessionId;
	
	/** delay between click and panel opening */
	private static final int TOOLS_OPEN_DELAY_TIME = 50;
	protected FilterManager mFilterManager;
	
	private MyUIHandler mUIHandler;
	
	/** api key. */
	protected String mApiKey = "";
	/** The default result code. */
	private int pResultCode = RESULT_CANCELED;
	
	@Override
	protected void onCreate(Bundle paramBundle) {
		super.onCreate(paramBundle);
		setContentView(R.layout.crop_view_news);
		mImageView = (ImageViewTouch) findViewById( R.id.crop_image );
		mDrawingViewContainer = (ViewGroup) findViewById( R.id.crop_drawing_view_container );
		mInlineProgressLoader = findViewById( R.id.crop_image_loading_view );

		init();
		
		onInitializeUtils();
		initializeUI();
		
		// initiate the filter manager
		mUIHandler = new MyUIHandler( this );
		mFilterManager = new FilterManager( this, mUIHandler, mApiKey );
//		mFilterManager.setOnToolListener( this );
//		mFilterManager.setOnBitmapChangeListener( this );
//		mFilterManager.setDragLayer( mDragLayer );
		
		Uri srcUri = handleIntent( getIntent() );

		if ( srcUri == null ) {
			onSetResult( RESULT_CANCELED, null );
			finish();
			return;
		}

		LocalDataService data = mFilterManager.getService( LocalDataService.class );
		data.setSourceImageUri( srcUri );

		// download the requested image
		loadImage( srcUri );
		loadEgg();
	}
	
	private void loadEgg() {
		final EffectEntry entry= new EffectEntry( FilterLoaderFactory.Filters.CROP, R.drawable.feather_tool_icon_crop, R.string.crop);
		mUIHandler.postDelayed( new Runnable() {
			
			@Override
			public void run() {
				 mFilterManager.activateEffect(entry);
			}
		}, TOOLS_OPEN_DELAY_TIME );
	}
	
	String path = null;
	private void init() {
		path = getIntent().getStringExtra("path");
		Log.d("may", "path=" + path);
		mBitmap = BitmapFactory.decodeFile(path);
		
	}

	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.cancel:
			break;
//		case R.id.crop:
//			mCrop.crop(mBitmap);
//			break;
		case R.id.save:
//			inputDialog();
			break;
		}
	}

	/**
	 * Initialize ui.
	 */
	@SuppressWarnings("deprecation")
	private void initializeUI() {

		// register the toolbar listeners
		mImageView.setDoubleTapEnabled( false );
	}

	/**
	 * Initialize utility classes
	 */
	protected void onInitializeUtils() {
		UIUtils.init( this );
		Constants.init( this );
		NativeFilterProxy.init( this, null );
	}
	
	private static class MyUIHandler extends Handler {

		private WeakReference<CropImage2Activity> mParent;

		MyUIHandler( CropImage2Activity parent ) {
			mParent = new WeakReference<CropImage2Activity>( parent );
		}

		@Override
		public void handleMessage( Message msg ) {
			super.handleMessage( msg );

			CropImage2Activity parent = mParent.get();
			if ( null != parent ) {

				switch ( msg.what ) {
					case FilterManager.STATE_OPENING:
						break;

					case FilterManager.STATE_OPENED:
						break;

					case FilterManager.STATE_CLOSING:
						parent.mImageView.setVisibility( View.VISIBLE );
						break;

					case FilterManager.STATE_CLOSED:
						break;

					case FilterManager.STATE_DISABLED:
						break;

					case FilterManager.STATE_CONTENT_READY:
						parent.mImageView.setVisibility( View.GONE );
						break;

					case FilterManager.STATE_READY:
						break;
				}
			}
		}
	}
	

	/** inline progress loader. */
	private View mInlineProgressLoader;
	/** The maim image view. */
	private ImageViewTouch mImageView;

	/** The main drawing view container for tools implementing {@link ContentPanel}. */
	private ViewGroup mDrawingViewContainer;


	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onContentChanged()
	 */
	@Override
	public void onContentChanged() {
		super.onContentChanged();
	}
	String mOutputFilePath;

	/**
	 * Once you've chosen an image you can start the feather activity
	 * 
	 * @param uri
	 */
	private void startFeather( Uri uri ) {

		if ( !Utility.isExternalStorageAvilable() ) {
			return;
		}

		// create a temporary file where to store the resulting image
		File file = Utility.getNextFileName();
		if ( null != file ) {
			mOutputFilePath = file.getAbsolutePath();
		} else {
			new AlertDialog.Builder( this ).setTitle( android.R.string.dialog_alert_title ).setMessage( "Failed to create a new File" )
					.show();
			return;
		}

		Intent newIntent = new Intent( this, FeatherActivity.class );

		newIntent.putExtra( "From_Type", Constants.ACTIVITY_EDIT );
		
		// set the source image uri
		newIntent.setData( uri );

		// pass the required api_key and secret ( see
		// http://developers.aviary.com/ )
		newIntent.putExtra( "API_KEY", Utility.API_KEY );

		newIntent.putExtra( "output", Uri.parse( "file://" + mOutputFilePath ) );
		newIntent.putExtra( Constants.EXTRA_OUTPUT_FORMAT, Bitmap.CompressFormat.JPEG.name() );
		newIntent.putExtra( Constants.EXTRA_OUTPUT_QUALITY, 100 );
		newIntent.putExtra( Constants.EXTRA_TOOLS_DISABLE_VIBRATION, true );

		final DisplayMetrics metrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics( metrics );
		int max_size = Math.min( metrics.widthPixels, metrics.heightPixels );

		// you can pass the maximum allowed image size, otherwise feather will determine
		// the max size based on the device memory
		// Here we're passing the current display size as max image size because after
		// the execution of Aviary we're saving the HI-RES image so we don't need a big
		// image for the preview
		max_size = (int) ( (double) max_size / 0.8 );
		newIntent.putExtra( "max-image-size", max_size );

		// Enable/disable the default borders for the effects
		newIntent.putExtra( "effect-enable-borders", true );

		mSessionId = StringUtils.getSha256( System.currentTimeMillis() + Utility.API_KEY );
		Log.d( TAG, "session: " + mSessionId + ", size: " + mSessionId.length() );
		newIntent.putExtra( "output-hires-session-id", mSessionId );

		startActivity(newIntent);
	}
	
	public void saveBitmap(String dir,Bitmap bmp) {
		File file = new File(dir);
		String path = null;
		if (!file.exists())
			file.mkdirs();
		try {
			path = file.getPath() + "/upload.jpeg";
			FileOutputStream fileOutputStream = new FileOutputStream(path);
			bmp.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
			fileOutputStream.flush();
			fileOutputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	protected Uri handleIntent( Intent intent ) {

		LocalDataService service = mFilterManager.getService( LocalDataService.class );

		if ( intent != null && intent.getData() != null ) {
			Uri data = intent.getData();

			if ( SystemUtils.isIceCreamSandwich() ) {
				if ( data.toString().startsWith( "content://com.android.gallery3d.provider" ) ) {
					// use the com.google provider, not the com.android provider ( for ICS only )
					data = Uri.parse( data.toString().replace( "com.android.gallery3d", "com.google.android.gallery3d" ) );
				}
			}

			Bundle extras = intent.getExtras();
			if ( extras != null ) {
				Uri destUri = (Uri) extras.getParcelable( Constants.EXTRA_OUTPUT );
				mApiKey = extras.getString( Constants.API_KEY );

				if ( destUri != null ) {

					service.setDestImageUri( destUri );

					String outputFormatString = extras.getString( Constants.EXTRA_OUTPUT_FORMAT );
					if ( outputFormatString != null ) {
						CompressFormat format = Bitmap.CompressFormat.valueOf( outputFormatString );
						service.setOutputFormat( format );
					}
				}
				if ( extras.containsKey( Constants.EXTRA_HIDE_EXIT_UNSAVE_CONFIRMATION ) ) {
					mHideExitAlertConfirmation = extras.getBoolean( Constants.EXTRA_HIDE_EXIT_UNSAVE_CONFIRMATION );
				}

			}
			return data;
		}
		return null;
	}
	
	protected void loadImage( Uri data ) {

		if ( null != mDownloadTask ) {
			mDownloadTask.setOnLoadListener( null );
			mDownloadTask = null;
		}

		mDownloadTask = new DownloadImageAsyncTask( data );
		mDownloadTask.setOnLoadListener( this );
		mDownloadTask.execute( getBaseContext() );
	}
	
	/** Main image downloader task **/
	private DownloadImageAsyncTask mDownloadTask;

	/** The Constant ALERT_CONFIRM_EXIT. */
	private static final int ALERT_CONFIRM_EXIT = 0;
	/** The Constant ALERT_DOWNLOAD_ERROR. */
	private static final int ALERT_DOWNLOAD_ERROR = 1;
	/** The Constant ALERT_REVERT_IMAGE. */
	private static final int ALERT_REVERT_IMAGE = 2;

	/** hide exit alert confirmation. */
	protected boolean mHideExitAlertConfirmation = false;
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.aviary.android.feather.async_tasks.DownloadImageAsyncTask.OnImageDownloadListener#onDownloadStart()
	 */
	@Override
	public void onDownloadStart() {
		mImageView.setVisibility( View.INVISIBLE );
		mInlineProgressLoader.setVisibility( View.VISIBLE );
	}
	@SuppressWarnings("deprecation")
	@Override
	public void onDownloadError( String error ) {
		mDownloadTask = null;
		hideProgressLoader();
		showDialog( ALERT_DOWNLOAD_ERROR );
	}

	@Override
	public void onDownloadComplete( Bitmap result, ImageSizes sizes ) {

		mDownloadTask = null;

		mImageView.setImageBitmap( result, true, null, UIConfiguration.IMAGE_VIEW_MAX_ZOOM );

		Animation animation = AnimationUtils.loadAnimation( this, android.R.anim.fade_in );
		animation.setFillEnabled( true );

		mImageView.setVisibility( View.VISIBLE );
		mImageView.startAnimation( animation );

		hideProgressLoader();

		int[] originalSize = { -1, -1 };
		if ( null != sizes ) {
			originalSize = sizes.getRealSize();
			onImageSize( sizes.getOriginalSize(), sizes.getNewSize(), sizes.getBucketSize() );
		}

		if ( mFilterManager != null ) {
			if ( mFilterManager.getEnabled() ) {
				mFilterManager.onReplaceImage( result, originalSize );
			} else {
				mFilterManager.onActivate( result, originalSize );
			}
		}

		computeOriginalFilePath();
		loadExif();
	}

	protected void onImageSize( String originalSize, String scaledSize, String bucket ) {
		HashMap<String, String> attributes = new HashMap<String, String>();
		attributes.put( "originalSize", originalSize );
		attributes.put( "newSize", scaledSize );
		attributes.put( "bucketSize", bucket );
	}
	/**
	 * Hide progress loader.
	 */
	private void hideProgressLoader() {
		Animation fadeout = new AlphaAnimation( 1, 0 );
		fadeout.setDuration( getResources().getInteger( R.integer.feather_config_mediumAnimTime ) );
		fadeout.setAnimationListener( new AnimationListener() {

			@Override
			public void onAnimationStart( Animation animation ) {}

			@Override
			public void onAnimationRepeat( Animation animation ) {}

			@Override
			public void onAnimationEnd( Animation animation ) {
				mInlineProgressLoader.setVisibility( View.GONE );
			}
		} );

		mInlineProgressLoader.startAnimation( fadeout );
	}
	/**
	 * Try to compute the original file absolute path
	 */
	protected void computeOriginalFilePath() {
		final LocalDataService data = mFilterManager.getService( LocalDataService.class );
		if ( null != data ) {
			data.setSourceImagePath( null );
			Uri uri = data.getSourceImageUri();
			if ( null != uri ) {
				String path = IOUtils.getRealFilePath( this, uri );
				if ( null != path ) {
					data.setSourceImagePath( path );
				}
			}
		}
	}

	/**
	 * load the original file EXIF data and store the result into the local data instance
	 */
	protected void loadExif() {
		final LocalDataService data = mFilterManager.getService( LocalDataService.class );
		ThreadPoolService thread = mFilterManager.getService( ThreadPoolService.class );
		if ( null != data && thread != null ) {
			final String path = data.getSourceImagePath();

			FutureListener<Bundle> listener = new FutureListener<Bundle>() {

				@Override
				public void onFutureDone( Future<Bundle> future ) {
					try {
						Bundle result = future.get();
						if ( null != result ) {
							data.setOriginalExifBundle( result );
						}
					} catch ( Throwable e ) {
						e.printStackTrace();
					}
				}
			};

			if ( null != path ) {
				thread.submit( new ExifTask(), listener, path );
			} else {
			}
		}
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onCreateDialog(int)
	 */
	@Override
	protected Dialog onCreateDialog( int id ) {

		Dialog dialog = null;

		switch ( id ) {
			case ALERT_CONFIRM_EXIT:
				dialog = new AlertDialog.Builder( this ).setTitle( R.string.confirm ).setMessage( R.string.confirm_quit_message )
						.setPositiveButton( R.string.yes_leave, new DialogInterface.OnClickListener() {

							@Override
							public void onClick( DialogInterface dialog, int which ) {
								dialog.dismiss();
								onBackPressed( true );
							}
						} ).setNegativeButton( R.string.keep_editing, new DialogInterface.OnClickListener() {

							@Override
							public void onClick( DialogInterface dialog, int which ) {
								dialog.dismiss();
							}
						} ).create();
				break;

			case ALERT_DOWNLOAD_ERROR:
				dialog = new AlertDialog.Builder( this ).setTitle( R.string.attention )
						.setMessage( R.string.error_download_image_message ).create();
				break;

			case ALERT_REVERT_IMAGE:
				dialog = new AlertDialog.Builder( this ).setTitle( R.string.revert_dialog_title )
						.setMessage( R.string.revert_dialog_message )
						.setPositiveButton( android.R.string.yes, new DialogInterface.OnClickListener() {

							@Override
							public void onClick( DialogInterface dialog, int which ) {
								dialog.dismiss();
								onRevert();
							}
						} ).setNegativeButton( android.R.string.no, new DialogInterface.OnClickListener() {

							@Override
							public void onClick( DialogInterface dialog, int which ) {
								dialog.dismiss();
							}
						} ).create();
				break;
		}

		return dialog;
	}

	/**
	 * Revert the original image.
	 */
	private void onRevert() {

		LocalDataService service = mFilterManager.getService( LocalDataService.class );
		loadImage( service.getSourceImageUri() );
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onBackPressed()
	 */
	@SuppressWarnings("deprecation")
	@Override
	public void onBackPressed() {
		if ( !mFilterManager.onBackPressed() ) {

			if ( mFilterManager.getBitmapIsChanged() ) {

				if ( mHideExitAlertConfirmation ) {
					super.onBackPressed();
				} else {
					showDialog( ALERT_CONFIRM_EXIT );
				}
			} else {
				super.onBackPressed();
			}
		}
	}

	/**
	 * On back pressed.
	 * 
	 * @param force
	 *           the super backpressed behavior
	 */
	protected void onBackPressed( boolean force ) {
		if ( force )
			super.onBackPressed();
		else
			onBackPressed();
	}
	/**
	 * Override the internal setResult in order to register the internal close status.
	 * 
	 * @param resultCode
	 *           the result code
	 * @param data
	 *           the data
	 */
	protected final void onSetResult( int resultCode, Intent data ) {
		pResultCode = resultCode;
		setResult( resultCode, data );
	}

	@Override
	public ImageViewTouchBase getMainImage() {
		return mImageView;
	}

	@Override
	public BottombarViewFlipper getBottomBar() {
		return null;
	}

	@Override
	public ViewGroup getOptionsPanelContainer() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ViewGroup getDrawingImageContainer() {
		return mDrawingViewContainer;
	}

	@Override
	public void showToolProgress() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void hideToolProgress() {
		// TODO Auto-generated method stub
		
	}
	private IToast mToastLoader;
	@Override
	public void showModalProgress() {
		if ( mToastLoader == null ) {
			mToastLoader = UIUtils.createModalLoaderToast();
		}
		mToastLoader.show();
		
	}

	@Override
	public void hideModalProgress() {
		if ( mToastLoader != null ) {
			mToastLoader.hide();
		}
		
	}

	@Override
	public ToolbarView getToolbar() {
		return null;
	}
}
